#include "EngineWin32.h"

VOID CALLBACK TimerProc (HWND hwnd, UINT msg, UINT_PTR id, DWORD time)
{
	EngineWin32::_this->_timers.find(id)->second->OnTick();
	EngineWin32::_this->_dirty = TRUE;
}

Timer::Timer(int interval)
{
	_id = SetTimer(NULL,0,interval,TimerProc);
	EngineWin32::_this->_timers.insert(pair<UINT_PTR,Timer*>(_id,this));
}

Timer::~Timer()
{
	EngineWin32::_this->_timers.erase(EngineWin32::_this->_timers.find(_id));
	KillTimer(NULL,_id);
}

LRESULT WINAPI WndProc(HWND hwnd, UINT msg, WPARAM wpar, LPARAM lpar) {
	switch(msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_KEYDOWN:
		if(!EngineWin32::_this->_key[wpar])
		{
			EngineWin32::_this->_key[wpar] = TRUE;
			EngineWin32::_this->OnKeyDown((BYTE)wpar);
		}
		EngineWin32::_this->_dirty = TRUE;
		return 0;
	case WM_KEYUP:
		if(EngineWin32::_this->_key[wpar])
		{
			EngineWin32::_this->_key[wpar] = FALSE;
			EngineWin32::_this->OnKeyUp((BYTE)wpar);
		}
		EngineWin32::_this->_dirty = TRUE;
		return 0;
	default:
		return DefWindowProc(hwnd, msg, wpar, lpar);
	}
}

EngineWin32* EngineWin32::_this = NULL;

EngineWin32::EngineWin32(LPCSTR title)
{
	_this = this;
	
	//get instance
	printf("get instance...");
	hinstance = GetModuleHandle(NULL);
	printf("done.\n");

	// register window class
	printf("register window class...");
	WNDCLASS wndclass;
	wndclass.style			= 0x00000000;					// class share device context
	wndclass.lpfnWndProc	= WndProc;						// universal/unique processor
	wndclass.cbClsExtra		= 0;							// system default / no extra
	wndclass.cbWndExtra		= 0;							// system default / no extra
	wndclass.hInstance		= hinstance;					// handle of instance
	wndclass.hIcon			= LoadIcon(0, IDI_APPLICATION);	// default icon
	wndclass.hCursor		= LoadCursor(0, IDC_ARROW);		// default cursor
	wndclass.hbrBackground	= NULL;							// no background auto-paint
	wndclass.lpszMenuName	= NULL;							// no menu
	wndclass.lpszClassName	= "Default";					// name: for windows and dx use
	if(!RegisterClass(&wndclass))
	{
		exit(-1);
	}
	printf("done.\n");

	// create window
	printf("create window...");
	DWORD style = WS_CAPTION| WS_SYSMENU| WS_MINIMIZEBOX| WS_VISIBLE;
	RECT rc = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
	if(!AdjustWindowRect(&rc, style, FALSE))
	{
		exit(-1);
	}
	if(!(hwnd = CreateWindow(
		"Default",			// window class registered before
		title,				// caption
		style,				// minimizable, captionated, unsizable, visible
		100,				// x
		100,				// y
		rc.right - rc.left,	// width
		rc.bottom - rc.top,	// height
		NULL,				// no parent window
		NULL,				// no menu
		hinstance,			// this instance
		NULL				// no extra info
	)))
	{
		exit(-1);
	}
	printf("done.\n");

	_dirty = TRUE;

	for(int i=0; i<256; i++)
	{
		_key[i] = FALSE;
	}
}

EngineWin32::~EngineWin32()
{

}

void EngineWin32::Run()
{
	OnLoad();

	MSG msg = {};
	while(msg.message != WM_QUIT)
	{
		//check event
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			DispatchMessage(&msg);
		}

		//redraw
		if(_dirty)
		{
			Redraw();
			_dirty = FALSE;
			Sleep(20);
			_dirty = TRUE;
		}
	}
}
